﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

public static class StringExtension
{
    /// <summary>
    /// <summary>
    /// 字符串转Unicode
    /// </summary>
    /// <param name="source">源字符串</param>
    /// <returns>Unicode编码后的字符串</returns>
    public static string String2Unicode(this string source)
    {
        byte[] bytes = Encoding.Unicode.GetBytes(source);
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < bytes.Length; i += 2)
        {
            stringBuilder.AppendFormat("\\u{0}{1}", bytes[i + 1].ToString("x").PadLeft(2, '0'), bytes[i].ToString("x").PadLeft(2, '0'));
        }
        return stringBuilder.ToString();
    }

    /// <summary>
    /// Unicode转字符串
    /// </summary>
    /// <param name="source">经过Unicode编码的字符串</param>
    /// <returns>正常字符串</returns>
    public static string Unicode2String(this string source)
    {
        return new Regex(@"\\u([0-9A-F]{4})", RegexOptions.IgnoreCase | RegexOptions.Compiled).Replace(
                     source, x => string.Empty + Convert.ToChar(Convert.ToUInt16(x.Result("$1"), 16)));
    }

    public static string ConvertToChinese(this string unicode)
    {
        // 假设格式是 u0000v，将其转换为 \u0000
        string fixedUnicode = unicode.Substring(2) + " "; // 添加空格用于分隔
        fixedUnicode = Regex.Replace(fixedUnicode, "u(\\w{4})", "\\\\u$1");

        // 使用Char.ConvertFromUtf32将Unicode编码转换为字符
        try
        {
            int unicodeInt = Convert.ToInt32(fixedUnicode.Substring(2), 16);
            string chineseChar = Char.ConvertFromUtf32(unicodeInt);
            return chineseChar;
        }
        catch
        {
            return "Invalid Unicode sequence";
        }
    }

    public static DateTime? TryDateTime(this string? dateTime)
    {
        if (dateTime.IsNull())
        {
            return null;
        }
        DateTime.TryParse(dateTime, out DateTime t);
        if (t == default(DateTime)) return null;
        return t;
    }
    public static DateOnly? TryDateOnly(this string? dateonly)
    {
        if (dateonly.IsNull())
        {
            return null;
        }
        DateOnly.TryParse(dateonly, out DateOnly t);
        if (t == default(DateOnly)) return null;
        return t;
    }
    public static int? TryInt(this string? @int)
    {
        if (@int.IsNull())
        {
            return null;
        }
        int.TryParse(@int, out int t);
        return t;
    }
    public static decimal? TryDecimal(this string? @decimal)
    {
        if (@decimal.IsNull())
        {
            return null;
        }
        decimal.TryParse(@decimal, out decimal t);
        return t;
    }
    public static double? TryDouble(this string? @double)
    {
        if (@double.IsNull())
        {
            return null;
        }
        double.TryParse(@double, out double t);
        return t;
    }
    public static long? TryLong(this string? @long)
    {
        if (@long.IsNull())
        {
            return null;
        }
        long.TryParse(@long, out long t);
        return t;
    }
    public static long? TryUInt16(this string? @uint)
    {
        if (@uint.IsNull())
        {
            return null;
        }
        UInt16.TryParse(@uint, out UInt16 t);
        return t;
    }


    /// <summary>
    /// By default, pascalize converts strings to UpperCamelCase also removing underscores
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public static string Pascalize(this string input)
    {
        return Regex.Replace(input, "(?:^|_| +)(.)", match => match.Groups[1].Value.ToUpper());
    }

    /// <summary>
    /// Same as Pascalize except that the first character is lower case
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public static string Camelize(this string input)
    {
        var word = input.Pascalize();
        return word.Length > 0 ? word.Substring(0, 1).ToLower() + word.Substring(1) : word;
    }


    public static StringBuilder Appends(this StringBuilder builder, params string[] contents)
    {
        if (contents != null && contents.Length > 0)
        {
            foreach (var item in contents)
            {
                builder.Append(item);
            }
        }
        return builder;
    }
    public static StringBuilder AppendIf(this StringBuilder builder, bool condition, string content)
    {
        if (condition)
        {
            builder.Append(content);
        }
        return builder;
    }
    public static StringBuilder AppendLineIf(this StringBuilder builder, bool condition, string content)
    {
        if (condition)
        {
            builder.AppendLine(content);
        }
        return builder;
    }

    /// <summary>
    /// 判断字符串是否为Null、空
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static bool IsNull(this string? s)
    {
        return string.IsNullOrWhiteSpace(s);
    }

    /// <summary>
    /// 判断字符串是否不为Null、空
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static bool NotNull(this string? s)
    {
        return !string.IsNullOrWhiteSpace(s);
    }


    /// <summary>
    /// 判断字符串是否全是英文
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static bool IsLetter(this string? text)
    {
        if (text.IsNull()) return true;
        var r = true;
        for (int i = 0; i < text.Length; i++)
        {
            if ((int)text[i] > 127)
            {
                r = false;
                break;
            }
        }
        return r;
    }


    /// <summary>
    /// 与字符串进行比较，忽略大小写
    /// </summary>
    /// <param name="s"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public static bool EqualsIgnoreCase(this string s, string value)
    {
        return s.Equals(value, StringComparison.OrdinalIgnoreCase);
    }

    /// <summary>
    /// 首字母转小写
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static string FirstCharToLower(this string s)
    {
        if (string.IsNullOrEmpty(s))
            return s;

        string str = s.First().ToString().ToLower() + s.Substring(1);
        return str;
    }

    /// <summary>
    /// 首字母转大写
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static string FirstCharToUpper(this string s)
    {
        if (string.IsNullOrEmpty(s))
            return s;

        string str = s.First().ToString().ToUpper() + s.Substring(1);
        return str;
    }

    /// <summary>
    /// 转为Base64，UTF-8格式
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static string ToBase64(this string s)
    {
        return s.ToBase64(Encoding.UTF8);
    }

    /// <summary>
    /// 转为Base64
    /// </summary>
    /// <param name="s"></param>
    /// <param name="encoding">编码</param>
    /// <returns></returns>
    public static string? ToBase64(this string s, Encoding encoding)
    {
        if (s.IsNull())
            return null;
        var bytes = encoding.GetBytes(s);
        return Convert.ToBase64String(bytes);// bytes.ToBase64();
    }

    public static string ToPath(this string s)
    {
        if (s.IsNull())
            return string.Empty;

        return s.Replace(@"\", "/");
    }


    public static string PadRightEx(this string str, int totalByteCount, char c = ' ')
    {
        int dcount = Encoding.GetEncoding("GB18030").GetBytes(str).Length;
        string w = str.PadRight(totalByteCount - dcount, c);
        return w + dcount;
    }
    public static string PadRightEx(this string str, int totalByteCount)
    {
        Encoding coding = Encoding.GetEncoding("GB18030");
        int dcount = 0;
        foreach (char ch in str.ToCharArray())
        {
            if (coding.GetByteCount(ch.ToString()) == 2)
                dcount++;
        }
        string w = str.PadRight(totalByteCount - dcount);
        return w;
    }

    public static string PadLeftEx(this string str, int totalByteCount)
    {
        Encoding coding = Encoding.GetEncoding("GB18030");
        int dcount = 0;
        foreach (char ch in str.ToCharArray())
        {
            if (coding.GetByteCount(ch.ToString()) == 2)
                dcount++;
        }
        string w = str.PadLeft(totalByteCount - dcount);
        return w;
    }

    /// <summary>
    /// 截取文本，区分中英文字符，中文算两个长度，英文算一个长度
    /// </summary>
    /// <param name="str">待截取的字符串</param>
    /// <param name="length">需计算长度的字符串</param>
    /// <returns>string</returns>
    public static string CutString(this string? str, int length)
    {
        if (string.IsNullOrWhiteSpace(str)) return "";
        string temp = str;
        int j = 0;
        int k = 0;
        for (int i = 0; i < temp.Length; i++)
        {
            if (Regex.IsMatch(temp.Substring(i, 1), @"[\u4e00-\u9fa5]+"))
            {
                j += 2;
            }
            else
            {
                j += 1;
            }
            if (j < length)
            {
                k += 1;
            }
            if (j >= length)
            {
                return temp.Substring(0, k);
            }
        }
        return temp;
    }

    /// <summary>
    /// 转成 /开台的路径段。
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static string ToPathField(this string s)
    {
        if (s.IsNull())
            return string.Empty;

        s = s.Replace(@"\", "/");
        if (!s.StartsWith("/")) s = "/" + s;
        if (s.EndsWith("/")) s = s.Substring(0, s.Length - 1);
        return s;
    }
}
